<?php
declare (strict_types = 1);

namespace app\access\controller;

use app\access\model\Admin;
use app\adminapi\extend\tools\jwt\JWT;
use thans\jwt\facade\JWTAuth;
use think\facade\Db;
use think\Request;

class Login
{
//    /**
//     * 学习无限级分类
//     */
//    public function recursion(){
//        // 第一种方法
////        引用算法
//        $arr = [
//            [
//                'id' => 1,
//                'name' => 'zhangsan'
//            ],
//        ];
//
//        # 修改数组中姓名的值该lisi is_ref is_count
//        foreach ($arr as &$value) {
//            $value['name'] = 'list';
//        }
//
//        # 数组中的name值不会改变？
//
//        dd($arr);
//
//    }

    /**
     * 递归、自己调用自己
     */
    public function recursion(){

        # 处理之前
//        默认 parent_id 0 的是一级分类
        $arr = [
            [
                'id' => 1,
                'name' => '菜单管理',
                'parent_id' => 0
            ],
            [
                'id' => 3,
                'name' => '添加菜单',
                'parent_id' => 1
            ]
        ];

        # 怎么通过递归实现我们想要的结果？


        # 处理结果
        $arr = [
            'id' => 1,
            'name' => '菜单管理',
            'children' => [
                'id' => 3,
                'name' => '添加菜单'
            ],
        ];


    }


    /**
     * 登录方法
     */
    public function login(Request $request){

        $username = $request->post('username');
        $password = $request->post('password');
//        ... 验证参数
        $userInfo = Admin::where('username',$username)->findOrEmpty();

        if ($userInfo->password != md5($password)) {
           return fail(2001,'密码错误');// 调用公共响应方法
        }

        # 登录成功后、获取登录用户的权限 用户id=》角色id=》权限id=》权限 =》 放在哪个位置？
        # 权限是访问的具体某个控制器、和方法

        # 使用DB方法获取权限
//        $this->getDbAccess($userInfo->id);

        # 通过模型查询权限
        $this->getModelAccess($userInfo->id);

        # 登录成功、颁发token认证
//        $token = JWT::getToken($userInfo->id); // 自己封装的
        // builder(负载参数)
        $token = JWTAuth::builder(['id' => $userInfo->id]);
//        $token = JWTAuth::token();
//        JWTAuth::invalidate($token);

        return  success(['token' => $token]);
    }

    /**
     * 通过DB方法查询权限
     */
    private function getDbAccess($user_id){
        # 原生sql、昨天
        # DB
        $data = Db::name('admin')
            ->join('admin_role','admin.id=admin_role.admin_id') // 根据用户id、查询角色id

            ->where('admin.id',$user_id)->find();

        # 根据角色id、查询对应的权限
        $role_id = $data['role_id'];

        $auth = Db::name('role_auth')
            ->join('auth','auth.id=role_auth.auth_id')
            ->where('role_auth.role_id',$role_id)// 角色id
            ->where('is_nav',0)
            ->select();
        # 判断用户是否登录？在中间件里面 是否有权限访问？
        # 模型关联查询权限？

//        $data = Admin::with('role')->find(1)->toArray();
//        dd($data);

        // 从DB的方式、改为模型关联怎么查询？


        # 查询处理的权限、可以放在缓存里面、需要进一步处理？
        # 当前用户拥有的权限
        $userAuth = [];//用户的权限
        foreach ($auth as $value) {
            # 控制器、方法
            $userAuth[] = $value['controller'].'/'.$value['action'];
        }
        # 退出、销毁token逻辑一致
        cache('userAuth'.$user_id,$userAuth);//存储用户的权限
    }

    /**
     * @param $user_id
     * @throws \think\Exception、
     */
    private function getModelAccess($user_id){

        # 根据用户查询到角色
        # 同理、根据角色查询权限
//        ['role','role.auth'] role 根据用户查询到角色  role（第二模型）.auth(关联的方法名)
        $authMessage = Admin::with(['role','role.auth'])->find($user_id)->toArray();
//        with()关联预载入 直接看到结果

//        $authMessage = Admin::find($user_id)->toArray();
//        $authMessage->role;
        # 存储用户对应的一个权限
        $userAuth = []; # 用户的权限
        foreach ($authMessage['role'] as $value) {
            foreach ($value['auth'] as $val) {
                $userAuth[] = $val['controller'].'/'.$val['action'];
            }
        }

        # 退出、销毁token逻辑一致
        cache('userAuth'.$user_id,$userAuth);//存储用户的权限
    }

}
